package web

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"

	"goEmqxToDb/config"
)

// Server HTTP服务器
type Server struct {
	port int
}

// NewServer 创建新的HTTP服务器
func NewServer(port int) *Server {
	return &Server{
		port: port,
	}
}

// Start 启动HTTP服务器
func (s *Server) Start() error {
	// 设置静态文件路由
	http.HandleFunc("/", s.handleStatic)

	// 设置API路由
	http.HandleFunc("/api/config", s.handleConfigAPI)

	addr := fmt.Sprintf(":%d", s.port)
	log.Printf("HTTP服务器启动在端口 %d", s.port)
	log.Printf("配置编辑器地址: http://localhost%s", addr)

	return http.ListenAndServe(addr, nil)
}

// handleStatic 处理静态文件
func (s *Server) handleStatic(w http.ResponseWriter, r *http.Request) {
	// 默认返回配置编辑器页面
	if r.URL.Path == "/" || r.URL.Path == "/index.html" {
		http.ServeFile(w, r, "static/config_editor.html")
		return
	}

	// 处理其他静态文件
	filePath := filepath.Join("static", r.URL.Path)
	http.ServeFile(w, r, filePath)
}

// handleConfigAPI 处理配置API
func (s *Server) handleConfigAPI(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Access-Control-Allow-Origin", "*")
	w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
	w.Header().Set("Access-Control-Allow-Headers", "Content-Type")

	// 处理预检请求
	if r.Method == "OPTIONS" {
		w.WriteHeader(http.StatusOK)
		return
	}

	switch r.Method {
	case "GET":
		s.getConfig(w, r)
	case "POST":
		s.saveConfig(w, r)
	default:
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
	}
}

// getConfig 获取配置
func (s *Server) getConfig(w http.ResponseWriter, r *http.Request) {
	configPath := "config/setting.json"

	// 检查配置文件是否存在
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		http.Error(w, "配置文件不存在", http.StatusNotFound)
		return
	}

	// 读取配置文件
	data, err := ioutil.ReadFile(configPath)
	if err != nil {
		log.Printf("读取配置文件失败: %v", err)
		http.Error(w, "读取配置文件失败", http.StatusInternalServerError)
		return
	}

	// 解析JSON
	var configs []config.Config
	if err := json.Unmarshal(data, &configs); err != nil {
		log.Printf("解析配置文件失败: %v", err)
		http.Error(w, "解析配置文件失败", http.StatusInternalServerError)
		return
	}

	// 返回JSON
	json.NewEncoder(w).Encode(configs)
}

// saveConfig 保存配置
func (s *Server) saveConfig(w http.ResponseWriter, r *http.Request) {
	// 读取请求体
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Printf("读取请求体失败: %v", err)
		http.Error(w, "读取请求体失败", http.StatusBadRequest)
		return
	}

	// 解析JSON
	var configs []config.Config
	if err := json.Unmarshal(body, &configs); err != nil {
		log.Printf("解析请求JSON失败: %v", err)
		http.Error(w, "解析请求JSON失败", http.StatusBadRequest)
		return
	}

	// 验证配置
	if len(configs) == 0 {
		http.Error(w, "配置不能为空", http.StatusBadRequest)
		return
	}

	// 确保config目录存在
	configDir := "config"
	if err := os.MkdirAll(configDir, 0755); err != nil {
		log.Printf("创建配置目录失败: %v", err)
		http.Error(w, "创建配置目录失败", http.StatusInternalServerError)
		return
	}

	// 格式化JSON
	formattedData, err := json.MarshalIndent(configs, "", "\t")
	if err != nil {
		log.Printf("格式化JSON失败: %v", err)
		http.Error(w, "格式化JSON失败", http.StatusInternalServerError)
		return
	}

	// 写入文件
	configPath := "config/setting.json"
	if err := ioutil.WriteFile(configPath, formattedData, 0644); err != nil {
		log.Printf("写入配置文件失败: %v", err)
		http.Error(w, "写入配置文件失败", http.StatusInternalServerError)
		return
	}

	log.Printf("配置文件保存成功: %s", configPath)

	// 返回成功响应
	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{
		"message": "配置保存成功",
		"path":    configPath,
	})
}
